<?php
declare (strict_types = 1);
namespace app\common\traits;
use Lcobucci\JWT\Configuration;
use Lcobucci\JWT\Signer\Hmac\Sha256;
use Lcobucci\JWT\Signer\Key;
use Lcobucci\JWT\Token\Plain;
use Lcobucci\Clock\Clock;
/**
 * Jwt生成函数
 */
trait Jwt {
    private $jwt_config;
    private $jwt;
    /**
     * 构造函数
     */
    private function init(){
        $this->jwt_config = config('JWT');
        $this->jwt = Configuration::forSymmetricSigner(
            // You may use any HMAC variations (256, 384, and 512)
            new Sha256(),
            // replace the value below with a key of your own!
            new Key($this->jwt_config['key'])
        );
    }
    /**
     * 生成JWT的token字符串
     *
     * @param [type] $uid
     * @return boolean
     */
    protected function issuing_token($uid)
    {
        $this->init();
        $now   = new \DateTimeImmutable;
        $token = $this->jwt->createBuilder()
          // Configures the issuer (iss claim)
          ->issuedBy($this->jwt_config['iss'])
          // Configures the audience (aud claim)
          ->permittedFor($this->jwt_config['aud'])
          // Configures the id (jti claim)
          ->identifiedBy($this->jwt_config['jti'])
          // Configures the time that the token was issue (iat claim)
          ->issuedAt($now)
          // Configures the time that the token can be used (nbf claim)
          ->canOnlyBeUsedAfter($now->modify($this->jwt_config['nbf']))
          // Configures the expiration time of the token (exp claim)
          ->expiresAt($now->modify($this->jwt_config['exp']))
          // Configures a new claim, called "uid"
          ->withClaim('uid', $uid)
          // Configures a new header, called "foo"
          // ->withHeader('foo', 'bar')
          // Builds a new token
          ->getToken($this->jwt->getSigner(), $this->jwt->getSigningKey());
        return $token->__toString();
    }
    /**
     * 解析jwt字符串
     */
    public function parse_token($token_str){
        $this->init();
        $this->jwt = Configuration::forSymmetricSigner(
            // You may use any HMAC variations (256, 384, and 512)
            new Sha256(),
            // replace the value below with a key of your own!
            new Key($this->jwt_config['key'])
        );
        // 解析Token字符串
        $token = $this->jwt->getParser()->parse($token_str);
        // 设置验证器
        $constraints = [
            new \Lcobucci\JWT\Validation\Constraint\IdentifiedBy($this->jwt_config['jti']),
            new \Lcobucci\JWT\Validation\Constraint\SignedWith(new Sha256(), new Key($this->jwt_config['key'])),
            new \Lcobucci\JWT\Validation\Constraint\ValidAt(new \fortuna\JwtClock())
        ];
        try {
            // 验证
            $this->jwt->getValidator()->assert($token, ...$constraints);
        } catch (InvalidToken $e) {
            throw $e;
        }
        return $token;
    }
}